/***************************************************
 ** @Desc : This file for 批量代付
 ** @Time : 2019.04.14 10:19
 ** @Author : Joker
 ** @File : bulk_pay
 ** @Last Modified by : Joker
 ** @Last Modified time: 2019.04.14 10:19
 ** @Software: GoLand
****************************************************/
package controllers

import (
	"encoding/json"
	"github.com/tealeg/xlsx"
	"mime/multipart"
	"path"
	"recharge/models"
	"recharge/sys"
	"recharge/utils"
	"recharge/utils/interface_config"
	"strconv"
	"strings"
	"time"
)

type BulkPay struct {
	KeepSession
}

var bandMdl = models.BankInfo{}

// 展示批量代付页面
// @router /merchant/show_bulk_pay_ui/ [get,post]
func (the *BulkPay) ShowBulkPayUI() {
	userName := the.GetSession("userName")
	if userName != nil {
		the.Data["userName"] = userName.(string)
	}
	right := the.GetSession("FilterRight")
	if right != nil {
		the.Data["right"] = right.(int)
	}

	the.TplName = "bulk_pay.html"
}

// 批量代付
// @router /merchant/do_bulk_pay/?:params [post]
func (the *BulkPay) DoBulkPay() {
	userId := the.GetSession("userId").(int)

	money := strings.TrimSpace(the.GetString("all_amount"))
	allRecords := strings.TrimSpace(the.GetString("all_records"))
	mobileNo := strings.TrimSpace(the.GetString("mobileNo"))
	mobileCode := strings.TrimSpace(the.GetString("mobileCode"))
	file, header, err := the.GetFile("file")

	//获取客户端ip
	ip := the.Ctx.Input.IP()

	var msg = utils.FAILED_STRING
	var flag = utils.FAILED_FLAG

	if err != nil {
		msg = "请上传批量文件! " + err.Error()
	} else {

		msg0, verify := payImpl.VerificationBulkPayInfo(money, allRecords, mobileNo)
		if verify {

			//手机验证码或ip白名单判断
			code := the.GetSession("bulk_pay_code")
			msg, verify = payImpl.VerificationSmgOrIP(userId, code, ip, mobileCode)
			cookie := the.Ctx.GetCookie("bulk_pay_sms_cookie") //两分钟失效
			if cookie == "" {
				the.SetSession("bulk_pay_code", "")
				the.SetSession("bulk_pay_sms_cookie", "")
			}

			if verify {
				msg, flag = handleFile(header, file, msg, allRecords, money, the, userId, mobileNo, flag)
			}
		} else {
			msg = msg0
		}
	}

	the.Data["json"] = globalMethod.JsonFormat(flag, "", msg, "")
	the.ServeJSON()
	the.StopRun()
}

func handleFile(header *multipart.FileHeader, file multipart.File, msg string, allRecords string, money string, the *BulkPay, userId int, mobileNo string, flag int) (string, int) {
	fileName := header.Filename
	defer file.Close()
	split := strings.Split(fileName, ".")
	if len(split) < 2 {
		msg = "请上传批量文件!"
	} else {

		fileType := split[1]
		if strings.Compare(strings.ToLower(fileType), "xls") != 0 &&
			strings.Compare(strings.ToLower(fileType), "xlsx") != 0 {
			msg = "仅支持“xls”、“xlsx”格式文件!"
		} else {
			b, _ := strconv.Atoi(allRecords) //循环记录数

			XFMerchant := merchantFactor.QueryOneMerchantForPay(money)
			if XFMerchant.MerchantNo == "" || XFMerchant.Id == 0 {
				msg = "请联系管理员更新代付通道"
			} else {

				//重命名文件
				fileName = split[0] + " - " + globalMethod.GetNowTimeV2() + globalMethod.RandomString(4) + ".xlsx"

				//保存文件
				filePath := "static/excel/pay/"
				_ = the.SaveToFile("file", path.Join(filePath, fileName))

				//读取文件内容
				xlFile, err := xlsx.OpenFile(filePath + fileName)
				if err != nil {
					msg = "文件内容错误！"
				} else {

					msg, flag = handleFileContent(xlFile, userId, XFMerchant, mobileNo, msg, flag, b)
				}
			}
		}
	}
	return msg, flag
}

func handleFileContent(xlFile *xlsx.File, userId int, merchant models.Merchant, mobileNo string, msg string, flag int, b int) (string, int) {
	sheet := xlFile.Sheets[0]
	//只读取文档中第一个工作表，忽略其他工作表
	for k, row := range sheet.Rows {
		if k == 0 || k == 1 { //忽略第一、二行数据
			continue
		}

		//出现空行，则忽略后面记录
		if row.Cells[0].String() == "" || row.Cells[5].String() == "" {
			break
		}

		record := models.WithdrawRecord{}
		record.UserId = userId
		record.MerchantNo = merchant.MerchantNo
		record.WhMobileNo = mobileNo

		record.SerialNumber = utils.XF + globalMethod.GetNowTimeV2() + globalMethod.RandomString(10)
		record.WhOrderId = utils.XF + globalMethod.GetNowTimeV2() + globalMethod.RandomString(8)

		record.WhAccountName = strings.TrimSpace(row.Cells[1].String()) //收款方户名
		record.WhAccountNo = strings.TrimSpace(row.Cells[2].String())   //收款方账号

		bankInfo := bandMdl.SelectOneBankInfo(row.Cells[3].String()) //收款方开户机构
		if bankInfo.BankId == "" {
			record.WhBankNo = row.Cells[3].String()
		} else {
			record.WhBankNo = bankInfo.BankId
		}

		//账户类型
		if strings.Compare("对私", row.Cells[4].String()) == 0 {
			record.WhUserType = "1"
		}
		if strings.Compare("对公", row.Cells[4].String()) == 0 {
			record.WhUserType = "2"
		}

		amount := strings.TrimSpace(row.Cells[5].String()) //金额
		//金额不正确，此条记录不通过
		verify := payImpl.VerificationBulkPayMoney(amount)
		if !verify {
			continue
		}

		yuanToFloat, _ := globalMethod.MoneyYuanToFloat(amount)
		record.WhAmount = yuanToFloat
		record.NoticeUrl = interface_config.XF_PAY_NOTICE_URL + record.WhOrderId

		record.Remark = row.Cells[8].String()

		nowTime := globalMethod.GetNowTime()
		record.CreateTime = nowTime
		record.EditTime = nowTime
		record.Status = utils.I

		// 多通道代付
		var enough = false
		switch merchant.ChannelType {
		case utils.XF:
			//先锋
			record.RecordType = utils.XF
			//判断可用余额,冻结提现金额
			enough, msg = userMdl.SelectOneUserUsableAmount(userId, yuanToFloat, record)

			if enough {
				// 4.0.0版本
				//result, err := xfPay(record, merchant.SecretKey)

				// 5.0.0版本
				encode := encrypt.EncodeMd5([]byte(globalMethod.RandomString(32)))
				result, err := xfPayV2(record, encode, merchant.SecretKey)
				if err != nil {
					msg = err.Error()
				} else {

					resp := models.XFPayResponseBody{}
					err = json.Unmarshal(result, &resp)
					if err != nil {
						sys.LogError("第", k+1, "条", "先锋代付响应数据格式错误:", err)
					} else {

						if strings.Compare("00000", resp.ResCode) == 0 ||
							strings.Compare("00001", resp.ResCode) == 0 ||
							strings.Compare("00002", resp.ResCode) == 0 {

							flag = utils.SUCCESS_FLAG
						} else {
							sys.LogDebug("第", k+1, "条", "先锋代付错误:", resp)
							msg = utils.FAILED_STRING
						}
					}
				}
			}
		}

		if !enough {
			break
		}

		if k == b+1 || k == 999 { //数据行数不得多于1000行
			break
		}

		time.Sleep(500 * time.Millisecond)
	}
	return msg, flag
}

// 代付发送短信验证码
// @router /merchant/do_bulk_pay_sms/?:params [post]
func (the *BulkPay) SendMsgDoBulkPay() {
	money := strings.TrimSpace(the.GetString("all_amount"))
	allRecords := strings.TrimSpace(the.GetString("all_records"))
	mobileNo := strings.TrimSpace(the.GetString("mobileNo"))

	var msg = utils.FAILED_STRING
	var flag = utils.FAILED_FLAG

	msg, verify := payImpl.VerificationBulkPayInfo(money, allRecords, mobileNo)
	if verify {
		loginName := the.GetSession("FilterUsers")
		if loginName == nil {
			msg = "浏览器请不要禁用cookie！"
		} else {
			u := userMdl.SelectOneUser(loginName.(string))
			ux := userExpandMdl.SelectOneUserInfoExpansion(u.Id)
			if ux.Ips != "" {
				msg = "已有IP白名单，无需发送验证码，输入任意字符即可！"
			} else {

				editCookie := the.Ctx.GetCookie("bulk_pay_sms_cookie")
				if editCookie == "" {
					the.SetSession("bulk_pay_sms_cookie", "")
				}

				cookieS := the.GetSession("bulk_pay_sms_cookie")
				codeCookie := ""
				if cookieS != nil {
					codeCookie = cookieS.(string)
				}

				if editCookie != "" || strings.Compare(editCookie, codeCookie) != 0 {
					msg = "请在2分钟后送登录验证码！"
				} else {
					code := globalMethod.RandomIntOfString(6)
					isSuccess := sms.SendSmsCode(u.Mobile, code)
					if !isSuccess {
						msg = "验证码发送失败，请联系管理员核实预留手机号是否正确！"
					} else {
						flag = utils.SUCCESS_FLAG
						the.SetSession("bulk_pay_code", code)

						cookie := globalMethod.RandomString(6)
						the.Ctx.SetCookie("bulk_pay_sms_cookie", cookie, 2*60)
						the.SetSession("bulk_pay_sms_cookie", cookie)

						msg = "验证码发送成功，且2分钟内有效！"
					}
				}
			}
		}
	}

	the.Data["json"] = globalMethod.JsonFormat(flag, "", msg, "")
	the.ServeJSON()
	the.StopRun()
}
